﻿using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using IndieStudio.BugsBang.Utility;
using UnityEngine.Events;

///Developed By Indie Studio
///https://assetstore.unity.com/publishers/9268
///www.indiestd.com
///info@indiestd.com

namespace IndieStudio.BugsBang.Game
{
	[DisallowMultipleComponent]
	public class Progress : MonoBehaviour
	{
		/// <summary>
		/// The star off sprite.
		/// </summary>
		public Sprite starOff;

		/// <summary>
		/// The star on sprite.
		/// </summary>
		public Sprite starOn;

		/// <summary>
		/// The level stars.
		/// </summary>
		public Image[] levelStars;

		/// <summary>
		/// The fill image reference.
		/// </summary>
		public Image fill;

		/// <summary>
		/// The finish call back holder.
		/// </summary>
		public Transform finishCallBackHolder;

		/// <summary>
		/// The finish call back.
		/// </summary>
		public string finishCallBack;

		/// <summary>
		/// Droped star flags.
		/// </summary>
		private bool [] dropedStar;

		/// <summary>
		/// The stars counter.
		/// </summary>
		[HideInInspector]
		public int starsCount;

		/// <summary>
		/// On progress finish call back.
		/// </summary>
		public UnityEvent onFinishCallBack;

		/// <summary>
		/// A static instance of this class.
		/// </summary>
		public static Progress instance;

		void Awake(){
			if (instance == null){
				instance = this;
			}
			SetUIThreeStars ();
		}

		// Use this for initialization
		void Start ()
		{
			dropedStar = new bool[3];
		}

		/// <summary>
		/// Set the value of the progress.
		/// </summary>
		/// <param name="currentTime">Current time.</param>
		public void SetProgress (float currentTime)
		{
			fill.fillAmount = 1 - (currentTime / (LevelsManager.instance.GetCurrentLevel().starsTimePeriod * 4.0f));

			if (currentTime > 0 && currentTime <= LevelsManager.instance.GetCurrentLevel().starsTimePeriod) {
				SetUIThreeStars ();
				starsCount = 3;
			} else if (currentTime > LevelsManager.instance.GetCurrentLevel().starsTimePeriod && currentTime <= (2.0f * LevelsManager.instance.GetCurrentLevel().starsTimePeriod)) {
				SetUITwoStars ();
				starsCount = 2;
				DropFirstStar ();
			} else if (currentTime > (2.0f * LevelsManager.instance.GetCurrentLevel().starsTimePeriod) && currentTime <= (4.0f * LevelsManager.instance.GetCurrentLevel().starsTimePeriod)) {	
				SetUIOneStar ();
				starsCount = 1;
				DropSecondStar ();
			} else {
				//0 Stars
				SetUIZeroStars();
				starsCount = 0;
				DropThirdStar ();

				onFinishCallBack.Invoke ();
			}
		}

		/// <summary>
		/// Set zero stars in the UI.
		/// </summary>
		private void SetUIZeroStars(){
			if (levelStars [0] != null) {
				levelStars [0].sprite = starOff;
			}
			if (levelStars [1] != null) {
				levelStars [1].sprite = starOff;
			}
			if (levelStars [2] != null) {
				levelStars [2].sprite = starOff;
			}
		}

		/// <summary>
		/// Set one star in the UI.
		/// </summary>
		private void SetUIOneStar(){
			//1 Star
			if (levelStars [0] != null) {
				levelStars [0].sprite = starOff;
			}
			if (levelStars [1] != null) {
				levelStars [1].sprite = starOff;
			}
			if (levelStars [2] != null) {
				levelStars [2].sprite = starOn;
			}
		}

		/// <summary>
		/// Set two stars in the UI.
		/// </summary>
		private void SetUITwoStars(){
			//2 Stars
			if (levelStars [0] != null) {
				levelStars [0].sprite = starOff;
			}
			if (levelStars [1] != null) {
				levelStars [1].sprite = starOn;
			}
			if (levelStars [2] != null) {
				levelStars [2].sprite = starOn;
			}
		}

		/// <summary>
		/// Set three stars in the UI.
		/// </summary>
		private void SetUIThreeStars(){
			//3 Stars
			if (levelStars [0] != null) {
				levelStars [0].sprite = starOn;
			}
			if (levelStars [1] != null) {
				levelStars [1].sprite = starOn;
			}
			if (levelStars [2] != null) {
				levelStars [2].sprite = starOn;
			}
		}

		/// <summary>
		/// Drop the first star.
		/// </summary>
		private void DropFirstStar(){
			if (dropedStar [0]) {
				return;
			}

			dropedStar [0] = true;
			DropStarEffect (levelStars[0].transform);
		}

		/// <summary>
		/// Drop the second star.
		/// </summary>
		private void DropSecondStar(){
			if (dropedStar [1]) {
				return;
			}

			dropedStar [1] = true;
			DropStarEffect (levelStars[1].transform);
		}

		/// <summary>
		/// Drop the third star.
		/// </summary>
		private void DropThirdStar(){
			if (dropedStar [2]) {
				return;
			}

			dropedStar [2] = true;
			DropStarEffect (levelStars[2].transform);
		}

		/// <summary>
		/// Drop star effect.
		/// </summary>
		/// <param name="star">Star transform reference.</param>
		private void DropStarEffect(Transform star){
			if (star == null) {
				return;
			}

			GameObject tempInstance = Instantiate (star.gameObject, star.position, Quaternion.identity) as GameObject;
			tempInstance.GetComponent<Image> ().sprite = starOn;
			tempInstance.transform.SetParent (transform.parent);
			tempInstance.transform.localScale = star.localScale;

			tempInstance.GetComponent<Rotate> ().Enabled = false;
			tempInstance.GetComponent<RectTransform> ().SetAsLastSibling ();

			Rigidbody2D tempInstanceRB = tempInstance.GetComponent<Rigidbody2D> ();
			tempInstanceRB.isKinematic = false;
			tempInstanceRB.AddForce (new Vector2(0.1f,0.3f) * 80);
			tempInstanceRB.AddTorque (360);

			AudioSources.instance.PlayDropStarSFX ();

			Destroy (tempInstance, 3);
		}
	}
}